package node;

import lexer.LexType;
import parser.Parser;

import java.io.IOException;

public class UnaryExpNode extends ASTNode {
    public final String name = "<UnaryExp>";
    // UnaryExp → PrimaryExp | Ident '(' [FuncRParams] ')' | UnaryOp UnaryExp
    private PrimaryExpNode primaryExpNode;
    private String identNode;
    private FuncRParamsNode funcRParamsNode;
    private UnaryOpNode unaryOpNode;
    private UnaryExpNode unaryExpNode;

    public UnaryExpNode(PrimaryExpNode primaryExpNode) {
        this.primaryExpNode = primaryExpNode;
    }

    public UnaryExpNode(String identNode, FuncRParamsNode funcRParamsNode) {
        this.identNode = identNode;
        this.funcRParamsNode = funcRParamsNode;
    }

    public UnaryExpNode(UnaryOpNode unaryOpNode, UnaryExpNode unaryExpNode) {
        this.unaryOpNode = unaryOpNode;
        this.unaryExpNode = unaryExpNode;
    }

    public PrimaryExpNode getPrimaryExpNode() {
        return primaryExpNode;
    }

    public String getIdentNode() {
        return identNode;
    }

    public UnaryOpNode getUnaryOpNode() {
        return unaryOpNode;
    }

    public UnaryExpNode getUnaryExpNode() {
        return unaryExpNode;
    }

    public FuncRParamsNode getFuncRParamsNode() {
        return funcRParamsNode;
    }

    @Override
    public void show() throws IOException {
        if (primaryExpNode != null) {
            primaryExpNode.show();
        } else if (identNode != null) {
            Parser.parserWriter.write(LexType.IDENFR + " " + identNode + "\n");
            Parser.parserWriter.write(LexType.LPARENT + " " + "(" + "\n");
            if (funcRParamsNode != null) {
                funcRParamsNode.show();
            }
            Parser.parserWriter.write(LexType.RPARENT + " " + ")" + "\n");
        } else {
            unaryOpNode.show();
            unaryExpNode.show();
        }
        Parser.parserWriter.write(name + "\n");
    }

    public int calculate() {
        // 确定当前UnaryExp是常数或者常量的加减乘除计算，即一定可以被计算出具体的数值
        // 保证不是函数调用
        if (primaryExpNode != null) {
            return primaryExpNode.calculate();
        } else if (unaryOpNode != null) {
            int res = unaryExpNode.calculate();
            if (unaryOpNode.getUnaryOp() == '-') {
                return -res;
            } else if (unaryOpNode.getUnaryOp() == '!') {
                // 如果是0，返回1，如果不是0，返回0
                return res == 0 ? 1 : 0;
            } else {
                return res;
            }
        } else {
            // 函数调用
            return 0;
        }
    }

    public boolean canCaclulate() {
        if (primaryExpNode != null) {
            return primaryExpNode.canCaclulate();
        } else if (unaryOpNode != null) {
            return unaryExpNode.canCaclulate();
        } else {
            // 函数调用
            return false;
        }
    }

}
